package com.wn.icloud.common.utils;

import java.lang.reflect.Field;
import java.text.NumberFormat;
import java.time.Instant;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

/**
 * 排序工具
 *
 * @author star
 * @date 2019/4/24
 **/
public class CompareUtil {

    /**
     * 对集合内元素按照多个属性排序
     *
     * @param list
     * @param isAsc        true：升序 false:降序
     * @param sortNameAttr
     * @param <E>
     */
    public static <E> void sort(List<E> list, final boolean isAsc, final String... sortNameAttr) {
        Collections.sort(list, new Comparator<E>() {
            @Override
            public int compare(E o1, E o2) {
                int ret = 0;
                try {
                    for (String sortName : sortNameAttr) {
                        ret = compareObject(sortName, isAsc, o1, o2);
                        if (0 != ret) {
                            break;
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return ret;
            }
        });
    }

    /**
     * 对集合中的每个元素都指定排序属性和升降序
     *
     * @param list
     * @param sortNameAttr
     * @param typeAttr
     * @param <E>
     */
    public static <E> void sort(List<E> list, final String[] sortNameAttr, final boolean[] typeAttr) {
        if (sortNameAttr.length != typeAttr.length) {
            throw new RuntimeException("属性数组元素和升降序数组元素个数不相等！");
        }
        Collections.sort(list, new Comparator<E>() {
            @Override
            public int compare(E o1, E o2) {
                int ret = 0;
                try {
                    for (int i = 0; i < sortNameAttr.length; i++) {
                        System.out.println("sortNameAttr[i]" + sortNameAttr[i]);
                        ret = compareObject(sortNameAttr[i], typeAttr[i], o1, o2);
                        if (0 != ret) {
                            break;
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return ret;
            }
        });
    }

    /**
     * 对2个对象按照指定属性名称进行排序
     *
     * @param sortName
     * @param isAsc
     * @param o1
     * @param o2
     * @param <E>
     * @return
     * @throws NoSuchFieldException
     * @throws IllegalAccessException
     */
    private static <E> int compareObject(final String sortName, final boolean isAsc, E o1, E o2) throws NoSuchFieldException, IllegalAccessException {
        int ret;
        Object value1 = CompareUtil.forceGetFieldValue(o1, sortName);
        Object value2 = CompareUtil.forceGetFieldValue(o2, sortName);
        String str1 = value1.toString();
        String str2 = value2.toString();
        if (value1 instanceof Number && value2 instanceof Number) {
            int maxlen = Math.max(str1.length(), str2.length());
            str1 = addZero2Str((Number) value1, maxlen);
            str2 = addZero2Str((Number) value2, maxlen);
        } else if (value1 instanceof Date && value2 instanceof Date) {
            long time1 = ((Date) value1).getTime();
            long time2 = ((Date) value2).getTime();
            int maxlen = Long.toString(Math.max(time1, time2)).length();
            str1 = addZero2Str(time1, maxlen);
            str2 = addZero2Str(time2, maxlen);
        } else if (value1 instanceof Instant && value2 instanceof Instant) {
            long time1 = ((Instant) value1).toEpochMilli();
            long time2 = ((Instant) value2).toEpochMilli();
            int maxlen = Long.toString(Math.max(time1, time2)).length();
            str1 = addZero2Str(time1, maxlen);
            str2 = addZero2Str(time2, maxlen);
        }
        if (isAsc) {
            ret = str1.compareTo(str2);
        } else {
            ret = str2.compareTo(str1);
        }
        return ret;
    }

    /**
     * 给数字对象按照指定长度在左侧补0
     *
     * @param numObj 数字
     * @param length 格式化长度
     * @return
     */
    public static String addZero2Str(Number numObj, int length) {
        NumberFormat nf = NumberFormat.getInstance();
        // 设置是否使用分组
        nf.setGroupingUsed(false);
        // 设置最大整数位数
        nf.setMaximumIntegerDigits(length);
        // 设置最小整数位数
        nf.setMinimumIntegerDigits(length);
        return nf.format(numObj);
    }

    /**
     * 强制获取对象的属性值
     *
     * @param object
     * @param fieldName
     * @return
     * @throws NoSuchFieldException
     * @throws IllegalAccessException
     */
    public static Object forceGetFieldValue(Object object, String fieldName) throws NoSuchFieldException, IllegalAccessException {
        Field field = object.getClass().getDeclaredField(fieldName);
        Object obj = null;
        System.out.println(field.getType());
        boolean accessAble = field.isAccessible();
        if (!accessAble) { // 如果是private或protect修饰的属性，强制改为可访问
            field.setAccessible(true);
            obj = field.get(object);
            field.setAccessible(accessAble);
            return obj;
        }
        obj = field.get(object);
        return obj;

    }


}
